package com.google.code.timeeditapplication.model.implementation;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.Scanner;

/**
 * A singleton class with methods to make Schedules out of icalendar files and
 * make icalendar files out of Schedules
 * 
 * @author deas
 * 
 */
public class ICal2Schedule {
	private static ICal2Schedule instance;
	private Scanner sc;

	private ICal2Schedule() {
		;
	}

	/**
	 * 
	 * @return instance of ICal2Schedule
	 */
	public static ICal2Schedule getInstance() {
		if (instance == null) {
			ICal2Schedule.instance = new ICal2Schedule();
		}
		return instance;
	}

	/**
	 * 
	 * @param fileName
	 *            path to icalendar file to convert into Schedule
	 * @param scheduleName
	 *            name of Schedule (e.g. 8H for class 8H's schedule)
	 * @return a Schedule object containing the events of the processed
	 *         icalendar file
	 */
	public Schedule fileToSchedule(final String fileName,
			final String scheduleName) throws FileNotFoundException {
		try {
			this.sc = new Scanner(new FileReader(fileName));
		} catch (final FileNotFoundException fne) {
			return null;
		}

		String metaData;
		int id = 0;
		String name = "", type = "", location = "";
		GregorianCalendar startTime = new GregorianCalendar(), endTime = new GregorianCalendar();

		final ArrayList<ScheduleItem> lessons = new ArrayList<ScheduleItem>();

		this.sc.useDelimiter("BEGIN:VEVENT");
		metaData = this.sc.next();

		this.sc.useDelimiter("DTSTART:");
		this.sc.next();

		while (this.sc.hasNext()) {
			this.sc.useDelimiter("DTEND:");
			final String start = this.sc.next().substring(8);
			startTime = new GregorianCalendar(Integer.parseInt(start.substring(
					0, 4)), Integer.parseInt(start.substring(4, 6)) - 1,
					Integer.parseInt(start.substring(6, 8)),
					Integer.parseInt(start.substring(9, 11)) + 1,
					Integer.parseInt(start.substring(11, 13)));

			this.sc.useDelimiter("SUMMARY:");
			final String end = this.sc.next().substring(6);
			endTime = new GregorianCalendar(Integer.parseInt(end
					.substring(0, 4)),
					Integer.parseInt(end.substring(4, 6)) - 1,
					Integer.parseInt(end.substring(6, 8)), Integer.parseInt(end
							.substring(9, 11)) + 1, Integer.parseInt(end
							.substring(11, 13)));

			this.sc.useDelimiter("LOCATION:");
			name = this.sc.next().substring(8).trim();
			this.sc.useDelimiter("DESCRIPTION:");
			this.sc.next();

			this.sc.useDelimiter("END:VEVENT");
			final String description = this.sc.next().substring(12);
			final int numberOfCommas = countSequence(description, ",");
			if (numberOfCommas > 1) {
				final int nextLastCommaPlace = description.lastIndexOf(",",
						description.lastIndexOf(",") - 1);
				location = description.substring(0, nextLastCommaPlace);
				type = description.substring(nextLastCommaPlace + 2,
						description.lastIndexOf(","));
				id = Integer.parseInt(description.substring(
						description.lastIndexOf("ID") + 3).trim());
			} else if (numberOfCommas == 1) {
				location = "n/a";
				type = description.substring(0, description.lastIndexOf(","));
				id = Integer.parseInt(description.substring(
						description.lastIndexOf("ID") + 3).trim());
			} else {
				location = "n/a";
				type = "n/a";
				id = Integer.parseInt(description.substring(
						description.lastIndexOf("ID") + 3).trim());
			}

			lessons.add(new ScheduleItem(id, name, type, location, startTime,
					endTime));
			this.sc.useDelimiter("DTSTART:");
			this.sc.next();
		}

		return new Schedule(lessons, scheduleName, metaData);
	}

	// counts the amount of presences of String seq in String str
	private int countSequence(final String str, final String seq) {
		int amount = 0;
		int start = 0;

		while ((start = str.indexOf(seq, start) + 1) != 0) {
			amount++;
		}
		return amount;
	}
}
